package io.github.iogogogo.commons.util;

import com.google.common.io.ByteStreams;
import com.google.common.io.CharSink;
import com.google.common.io.FileWriteMode;
import com.google.common.io.Files;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Created by tao.zeng on 2024/11/7.
 */
@Slf4j
public class IoUtils {

    public static void close(AutoCloseable... closeables) {
        if (Objects.isNull(closeables) || closeables.length == 0) return;
        try {
            for (AutoCloseable closeable : closeables) {
                closeable.close();
            }
        } catch (Exception e) {
            // ignore
        }
    }

    public static void writeForJava(String path, boolean append, CharSequence content) {
        try {
            checkPath(path);
            Path pathfile = Paths.get(path);
            if (!java.nio.file.Files.exists(pathfile)) java.nio.file.Files.createFile(pathfile);
            Path pathname = pathfile;
            if (append) {
                StandardOpenOption[] options = {StandardOpenOption.WRITE, StandardOpenOption.APPEND};
                java.nio.file.Files.write(pathname, charSequenceToBytes(content), options);
                java.nio.file.Files.write(pathname, charSequenceToBytes("\n"), options);
            } else {
                java.nio.file.Files.write(pathname, charSequenceToBytes(content), StandardOpenOption.WRITE);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    public static List<String> readLineForJava(String path) {
        try {
            return java.nio.file.Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }

    public static void writeForGuava(String path, boolean append, CharSequence content) {
        try {
            checkPath(path);
            CharSink charSink = append
                    ? Files.asCharSink(new File(path), StandardCharsets.UTF_8, FileWriteMode.APPEND)
                    : Files.asCharSink(new File(path), StandardCharsets.UTF_8);
            charSink.write(content);
            if (append) charSink.write("\n");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    public static List<String> readLineForGuava(String path) {
        try {
            return Files.asCharSource(new File(path), StandardCharsets.UTF_8).readLines();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }


    public static String readContent(String path) {
        try (InputStream fileInputStream = java.nio.file.Files.newInputStream(Paths.get(path))) {
            return new String(ByteStreams.toByteArray(fileInputStream));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private static byte[] charSequenceToBytes(CharSequence content) {
        if (StringUtils.isEmpty(content)) return new byte[]{};
        return content.toString().getBytes(StandardCharsets.UTF_8);
    }

    @SuppressWarnings("UnusedReturnValue")
    private static boolean checkPath(String path) {
        File parentPath = new File(path).getParentFile();
        boolean sign = parentPath.mkdirs();
        if (log.isDebugEnabled()) log.debug("{} {}", parentPath, sign ? "create succeed." : "already exist.");
        return sign;
    }
}
